#include "objectdata.h"
#include "symbol.h"
#include "map.h"
#include "game.h"
#include "creature.h"

Stairs::Stairs( bool down, Map& target, uint x, uint y )
: _down( down )
, _target( target )
, _targetX( x )
, _targetY( y )
{
}

bool Stairs::Symbol( IO::SymList* list ) const
{
    list->push_back( IO::Sym( _down ? '>' : '<', Colour( 128, 128, 128 ) ) );
    return true;
}

bool Stairs::Name( std::string* name, bool* plural, uint article ) const
{
    if ( name->empty() && article == ARTICLE_INDEFINITE )
        *name += "a ";
    if ( article == ARTICLE_PLURAL )
        *name += _down ? "descending staircases" : "ascending staircases";
    else
        *name += _down ? "descending staircase" : "ascending staircase";
    return true;
}

bool Stairs::Portal( Map** target, uint* x, uint* y, uint* type ) const
{
    *target = &_target;
    *x = _targetX;
    *y = _targetY;
    *type = _down ? PORTAL_DOWN : PORTAL_UP;
    return true;
}

bool Stairs::MemorySymbol( bool* memory, bool* tileMemory ) const
{
    *memory = true;
    *tileMemory = true;
    return true;
}

bool Stairs::Priority( int* priority ) const
{
    *priority -= 1000;
    return true;
}

bool Brazier::Symbol( IO::SymList* list ) const
{
    Colour c( 255, 255, 0 );
    list->push_back( IO::Sym( Sym::LOWIDIAERESIS,  c ) );
    list->push_back( IO::Sym( 'i',                 c ) );
    list->push_back( IO::Sym( Sym::LOWICIRCUMFLEX, c ) );
    list->push_back( IO::Sym( Sym::LOWIACUTE,      c ) );
    return true;
}

bool Brazier::Light( int* lightRange ) const
{
    *lightRange = std::max( *lightRange, 8 );
    return true;
}

bool Brazier::Blocking( bool* blocking, bool *losBlocking, uint* pushType ) const
{
    *blocking = true;
    *losBlocking = false;
    return true;
}

bool Brazier::Name( std::string* name, bool* plural, uint article ) const
{
    if ( name->empty() && article == ARTICLE_INDEFINITE )
        *name += "a ";
    if ( article == ARTICLE_PLURAL )
        *name += "braziers";
    else
        *name += "brazier";
    return true;
}

bool Brazier::Flammable( uint* flammableType ) const
{
    *flammableType |= FIRE_SOURCE_UNLIMITED;
    return true;
}

bool Brazier::OnLight( Creature* c, Behaved* target )
{
    Bank().TernarySwitch( TERNARY_ALIGHT_FROM_BRAZIER, c, target, this );
    target->Call< BIOnSetFire >();
    return true;
}

bool Brazier::MemorySymbol( bool* memory, bool* tileMemory ) const
{
    *memory = true;
    return true;
}

bool Crate::Symbol( IO::SymList* list ) const
{
    list->push_back( IO::Sym( Sym::BOX, Colour( 192, 128, 64 ) ) );
    return true;
}

bool Crate::Blocking( bool* blocking, bool *losBlocking, uint* pushType ) const
{
    uint fireType;
    Call< BIFire >( &fireType );
    *blocking = !( fireType & BIFire::FIRE_CHARRED );
    *losBlocking = false;
    *pushType = PUSH_MOVE;
    return true;
}

bool Crate::Name( std::string* name, bool* plural, uint article ) const
{
    if ( name->empty() && article == ARTICLE_INDEFINITE )
        *name += "a ";
    if ( article == ARTICLE_PLURAL )
        *name += "crates";
    else
        *name += "crate";
    return true;
}

bool Crate::Flammable( uint* flammableType ) const
{
    *flammableType |= FLAMMABLE_BURN_EXTRA_LONG | FLAMMABLE_SMOULDER_LONG | FLAMMABLE_CHAR;
    return true;
}

bool Crate::Priority( int* priority ) const
{
    *priority += 200;
    return true;
}